import type { BookType, JSON2SheetOpts, WorkBook, WritingOptions } from 'xlsx'
import * as xlsx from 'xlsx'

export interface ExcelData<T = any> {
  header: string[]
  results: T[]
  meta: { sheetName: string }
}

export interface JsonToSheet<T = any> {
  data: T[]
  header?: T
  filename?: string
  json2sheetOpts?: JSON2SheetOpts
  write2excelOpts?: WritingOptions
}

export interface AoAToSheet<T = any> {
  data: T[][]
  header?: T[]
  filename?: string
  write2excelOpts?: WritingOptions
}

export interface ExportModalResult {
  filename: string
  bookType: BookType
}

const { utils, writeFile } = xlsx

const DEF_FILE_NAME = 'excel-list.xlsx'

/**
 * 将 JSON 数据转换为 Excel 表格文件并下载。
 * @param param JSONToSheet<T> - 包含转换所需的参数对象
 * @param param.data T[] - 要转换为 Excel 表格的数据数组
 * @param param.header T[] - 可选，Excel 表格的表头，如果不提供，则默认使用数据数组的第一项作为表头
 * @param param.filename string - 可选，生成的 Excel 文件名，默认为 'sheet'
 * @param param.json2sheetOpts json2sheet.Options - 可选，传递给 json_to_sheet 函数的选项
 * @param param.write2excelOpts writeFile.Options - 可选，传递给 writeFile 函数的选项
 * @example
 * function exportExcel() {
    const data: any = tableProps.data.map((item, index) => {
      return {
        index: index + 1,
        returnVisitUserName:
          userInfo.value?.realName ?? userInfo.value?.username,
        ...item,
      }
    })
    ExcelUtils.jsonToSheetXlsx({
      data,
      header: {
        index: '序号',
        id: '记录ID',
        clueId: '线索ID',
        returnVisitUserName: '回访用户',
        returnVisitTime: '回访时间',
        returnVisitContent: '回访内容',
        department: '对接部门',
        contactPerson: '联系人',
        contactMatter: '联系事宜',
        remark: '备注',
      },
      filename: `回访记录${Date.now()}.xlsx`,
      json2sheetOpts: {
        // 指定顺序
        // header: ['contactPerson', 'returnVisitTime'],
      },
    })
  }
 */
export function jsonToSheetXlsx<T = any>({
  data,
  header,
  filename = DEF_FILE_NAME,
  json2sheetOpts = {},
  write2excelOpts = { bookType: 'xlsx' },
}: JsonToSheet<T>) {
  const arrData = [...data]
  if (header) {
    arrData.unshift(header)
    json2sheetOpts.skipHeader = true
  }

  const worksheet = utils.json_to_sheet(arrData, json2sheetOpts)

  /* add worksheet to workbook */
  const workbook: WorkBook = {
    SheetNames: [filename],
    Sheets: {
      [filename]: worksheet,
    },
  }
  /* output format determined by filename */
  writeFile(workbook, filename, write2excelOpts)
  /* at this point, out.xlsb will have been downloaded */
}

export function aoaToSheetXlsx<T = any>({
  data,
  header,
  filename = DEF_FILE_NAME,
  write2excelOpts = { bookType: 'xlsx' },
}: AoAToSheet<T>) {
  const arrData = [...data]
  if (header)
    arrData.unshift(header)

  const worksheet = utils.aoa_to_sheet(arrData)

  /* add worksheet to workbook */
  const workbook: WorkBook = {
    SheetNames: [filename],
    Sheets: {
      [filename]: worksheet,
    },
  }
  /* output format determined by filename */
  writeFile(workbook, filename, write2excelOpts)
  /* at this point, out.xlsb will have been downloaded */
}
